<template>
  <a-drawer
    title="通知列表"
    :maskClosable="true"
    :visible="visible"
    :width="modalWidth"
    @close="closeModal"
    :body-style="{
      height: 'calc(100% - 55px)',
      padding: 0,
    }"
    :destroyOnClose="true"
  >
    <a-row class="notice-list" type="flex" @scroll="handleListScroll">
      <a-col class="left" flex="1">
        <div style="padding: 0 10px; border-bottom: 1px solid #f1f1f1">
          <a-tabs v-model:activeKey="activeTabKey">
            <a-tab-pane
              v-for="item of TAB_LIST"
              :key="item.key"
              :tab="item.title"
            ></a-tab-pane>
          </a-tabs>
        </div>
        <a-empty v-if="listNoData" class="mt-20" />
        <ul class="list" v-else ref="listRef">
          <li
            v-for="item of messageList"
            :key="item.arrKey"
            class="message-item"
            :class="{
              'message-active': currentMessage.cat_label == item.cat_label,
            }"
            @click="handleListItemClick(item)"
          >
            <div class="avatar">
              <img :src="item.catInfo.icon" />
            </div>
            <div class="info">
              <div class="name">
                <span>{{ item.catInfo.name }}</span>
                <span class="time">{{ item.timeStr }}</span>
              </div>
              <div class="last-message">
                <span>{{ item.last_title }}</span>
                <a-badge :count="item.un_complete"> </a-badge>
              </div>
            </div>
          </li>
        </ul>
      </a-col>
      <a-col class="right" flex="2" v-show="showDetail">
        <div class="content" v-if="Object.keys(currentMessage).length">
          <div
            class="unread-count"
            @click="checkAllUnreadMessage"
            v-if="hiddenUnreadCount > 0 && detailList?.length"
          >
            <ArrowUpOutlined />
            <span class="ml-5"
              >继续上滑还有 {{ hiddenUnreadCount }} 条消息未读</span
            >
          </div>
          <div
            class="unread-count2"
            @click="checkNewMessage"
            v-if="newMessageCount > 0"
          >
            <DownOutlined />
            <span class="ml-5"> {{ newMessageCount }} 条新消息</span>
          </div>
          <div class="title">
            <div class="avatar">
              <img :src="currentMessage.catInfo.icon" />
            </div>
            <div class="info">
              <div class="name">{{ currentMessage.catInfo.name }}</div>
              <div class="intro">{{ currentMessage.catInfo.intro }}</div>
            </div>
          </div>
          <div
            class="list"
            ref="detailListRef"
            @scroll="handleDetailScroll"
          >
            <ul ref="detailRef">
              <!-- <li v-if="!detailHasMore" class="no-content">没有更多数据了</li> -->
              <li
                v-for="item of detailList"
                :key="item.id"
                class="detail-item"
                @mouseover="item.showBtn = true"
                @mouseleave="item.showBtn = false"
              >
                <div v-if="item.timeStr" class="show-time">
                  {{ item.timeStr }}
                </div>
                <a-card :title="item.title" size="small">
                  <template #extra>
                    <template v-if="item.unique_id && item.complete == 0">
                      <a-button
                        v-if="item.showBtn"
                        type="link"
                        size="small"
                        style="
                          height: 20px;
                          line-height: 20px;
                          padding-right: 0px;
                        "
                        @click.stop="setNoticeRead([], item.id)"
                      >
                        <template #icon>
                          <CheckOutlined />
                        </template>
                        完成
                      </a-button>
                      <a-badge v-else status="error" text="未完成" />
                    </template>
                  </template>
                  <div
                    v-if="
                      (item.content && Object.keys(item.content).length) ||
                      item.remark
                    "
                    class="list-content"
                  >
                    <a-row
                      v-for="(content, index) of item.content"
                      :key="index"
                      class="line-item"
                    >
                      <a-col :span="6">{{ content.title }}：</a-col>
                      <a-col
                        :span="18"
                        :style="{
                          color: content.color ? content.color : '#333',
                        }"
                        >{{ content.content }}</a-col
                      >
                    </a-row>
                    <a-row v-if="item.remark" class="line-item">
                      <a-col :span="6">备注：</a-col>
                      <a-col :span="18">{{ item.remark }}</a-col>
                    </a-row>
                  </div>
                  <div v-else class="no-content">暂无内容</div>
                  <div
                    class="check-detail"
                    v-if="item.link"
                    @click="toDetailLink(item)"
                  >
                    <span class="text-primary">查看详情</span>
                    <RightOutlined />
                  </div>
                </a-card>
              </li>
            </ul>
          </div>
        </div>
        <div class="empty" v-else>
          <a-empty description="请点击左侧通知分类查看" />
        </div>
      </a-col>
    </a-row>
    <notice-iframe
      :title="iframeTitle"
      :visible="iframeVisible"
      :url="iframeUrl"
      @cancel="iframeModalClose"
    />
  </a-drawer>
</template>

<script>
import {
  computed,
  defineComponent,
  nextTick,
  h,
  reactive,
  toRefs,
  watch,
} from "vue";
import request from "../../../common/utils/request";
import store from "../../../store";
import SocketService from "./utils/websocket";
import common from "./utils/common";
import {
  RightOutlined,
  ArrowUpOutlined,
  DownOutlined,
  CheckOutlined,
} from "@ant-design/icons-vue";
import { notification, Button, message } from "ant-design-vue";
import NoticeIframe from "./NoticeIframe.vue";
import utils from "../../../common/utils/utils";

export default defineComponent({
  name: "NoticeList",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    RightOutlined,
    ArrowUpOutlined,
    DownOutlined,
    CheckOutlined,
    NoticeIframe,
  },
  setup(props, { emit }) {
    const state = reactive({
      showDetail: true,
      activeTabKey: TAB_LIST[0].key,
      socketServe: SocketService.Instance,
      listPage: 1,
      listPageSize: 100,
      messageList: [],
      listHasMore: true,
      listNoData: true,
      currentMessage: {},
      detailPageSize: 100,
      detailHasMore: true,
      detailList: [],
      allUnComplete: 0,
      detailListRef: null,
      detailRef: null,
      oldScrollTop: 0,
      oldScrollHeight: 0,
      loadingDetail: false,
      newMessageCount: 0,
      listRef: null,
      oldListScrollTop: 0,
      listScrollHeight: 0,
      iframeTitle: "查看详情",
      iframeVisible: false,
      iframeUrl: "",
    });

    const systemIsOem = computed(
      () =>
        store.getters.basicConfig.oem_org_id &&
        store.getters.basicConfig.oem_org_id > 0
    );

    const modalWidth = computed(() =>
      state.showDetail ? LIST_WIDTH : INIT_WIDTH
    );

    // 继续上滑消息提示
    const hiddenUnreadCount = computed(() => {
      let unReadListCount = state.detailList.filter(item => item.complete == 0)?.length || 0;
      return state.currentMessage?.un_complete - unReadListCount;
    })

    const closeModal = () => {
      emit("cancel");
    };

    const iframeModalClose = () => {
      state.iframeVisible = false;
      state.iframeTitle = "";
      state.iframeUrl = "";
    };

    const showMessageDetail = () => {
      state.showDetail = true;
    };

    watch(
      () => state.activeTabKey,
      () => {
        state.listPage = 1;
        state.messageList = [];
        state.currentMessage = {};
        state.detailList = [];
        getMssageList();
      }
    );

    // 获取左侧消息列表
    const getMssageList = () => {
      let params = {
        page: state.listPage,
        pageSize: state.listPageSize,
        type: state.activeTabKey,
      }
      if (systemIsOem.value) {
        params.is_oem = 1;
      }
      request
        .get("/message", "/org/notice/category/list", params)
        .then((res) => {
          state.messageList = [...state.messageList, ...res.list];
          state.listHasMore = res.list.length === state.listPageSize;
          state.listNoData = state.listPage === 1 && res.list.length === 0;
          getListShowTime();
          nextTick(() => {
            state.listScrollHeight = state.listRef.scrollHeight;
          });
        });
    };
    const handleListScroll = (e) => {
      const scrollTop = e.target.scrollTop;
      state.oldListScrollTop = scrollTop;
      if (
        state.listHasMore &&
        state.listScrollHeight > 0 &&
        state.listScrollHeight - scrollTop < 100
      ) {
        // 请求下一页
        state.listPage++;
        getMssageList();
      }
    };
    const handleListItemClick = (current) => {
      console.log("handleListItemClick", current.cat_label);
      if (
        state.currentMessage &&
        state.currentMessage.cat_label == current.cat_label
      ) {
        return;
      }
      state.currentMessage = current;
      state.detailList = [];
      showMessageDetail();
      getMessageDetail(true);
    };
    const getListShowTime = () => {
      state.messageList.forEach((item) => {
        item.timeStr = common.getDateDiff(item.updated_at);
      });
      setTimeout(() => {
        getListShowTime();
      }, 30000);
    };

    // 获取右侧消息详情
    const getMessageDetail = (init = false) => {
      state.loadingDetail = true;
      let params = {
        cat_id: state.currentMessage.id,
        last_id: init ? 0 : state.detailList[0].id,
        pageSize: state.detailPageSize,
        allUnComplete: state.allUnComplete,
      };
      if (systemIsOem.value) {
        params.is_oem = 1;
      }
      if (state.activeTabKey == 1) {
        params.un_read = 1;
      }
      request
        .get("/message", "/org/notice/content/list", params)
        .then((res) => {
          state.detailList = init
            ? res.list
            : [...res.list, ...state.detailList];
          getDetailShowTime();
          setNoticeRead(res.list);
          state.detailHasMore = res.list.length === state.detailPageSize;
          state.loadingDetail = false;
          if (init) {
            setScrollTop({ toBottom: true });
          } else if ((state.allUnComplete = 1)) {
            setScrollTop({});
            state.allUnComplete = 0;
          } else {
            nextTick(() => {
              setScrollTop({
                position:
                  state.detailRef.scrollHeight - state.oldScrollHeight - 50,
              });
            });
          }
        });
    };
    const setNoticeRead = (list, id) => {
      let idArr = [];
      if (id) {
        idArr = [id];
      } else {
        list.forEach((item) => {
          if (!item.unique_id && item.complete == 0) {
            idArr.push(item.id);
          }
        });
      }
      if (idArr.length) {
        request.post("/message", "/org/notice/complete", {cat_id: state.currentMessage.id,unique_id_arr: idArr});
      }
    };
    const checkAllUnreadMessage = () => {
      state.allUnComplete = 1;
      getMessageDetail();
    };
    const checkNewMessage = () => {
      getMessageDetail(true);
      state.newMessageCount = 0;
    };
    const getDetailShowTime = () => {
      state.detailList.forEach((currentNotice, index) => {
        const currentUnixTime = common.getUnixTime(currentNotice.created_at);
        const currentTimerStr = common.getDateDiff(currentNotice.created_at);
        currentNotice.timeStr = "";
        if (index === 0) {
          currentNotice.timeStr = currentTimerStr;
        } else {
          const lastNotice = state.detailList[index - 1];
          const lastUnixTime = common.getUnixTime(lastNotice.created_at);
          const lastTimeStr = common.getDateDiff(lastNotice.created_at);
          if (
            lastTimeStr != currentTimerStr &&
            currentUnixTime - lastUnixTime > 300000
          ) {
            currentNotice.timeStr = currentTimerStr;
          } else {
            currentNotice.timeStr = "";
          }
        }
      });
      setTimeout(() => {
        getDetailShowTime();
      }, 30000);
    };
    const setScrollTop = ({ toBottom = false, position = 0 }) => {
      nextTick(() => {
        setTimeout(() => {
          if (toBottom) {
            state.oldScrollHeight = state.detailListRef.scrollTop =
              state.detailRef.scrollHeight;
          } else {
            state.oldScrollHeight = state.detailListRef.scrollTop = position;
          }
        }, 0);
      });
    };
    const handleDetailScroll = (e) => {
      const scrollTop = e.target.scrollTop;
      // console.log("handleDetailScroll", scrollTop);
      state.oldScrollTop = scrollTop;
      if (!state.loadingDetail && state.detailHasMore && scrollTop == 0) {
        // 请求下一页
        getMessageDetail();
      }
    };

    const toDetailLink = (current) => {
      const { link, title, link_frame } = current;
      if (link_frame) {
        // state.iframeUrl = link;
        if (current.link_original.includes("energyMeterList")) {
          message.warn("请在移动端进行操作");
          return;
        }
        state.iframeUrl = `${link}${
          link.indexOf("?") === -1 ? "?" : "&"
        }org_token=${utils.getStorage("org_token")}&from=pc`;
        console.log("iframeUrl", state.iframeUrl);
        state.iframeTitle = title;
        state.iframeVisible = true;
      } else {
        let url = link;
        // 租客审批特殊处理
        if (current.link_original) {
          let aliasArr = current.link_original.split("?");
          if (aliasArr.length > 1 && aliasArr[0] == "tenantApprovalDetail") {
            url = `${location.origin}/orgs/#/apps/workApproval/tenantApproval/detail?${aliasArr[1]}`;
          }
        }
        window.open(url);
      }
    };

    // 收取新消息通知
    watch(
      () => store.getters.messageTrigger,
      () => {
        nextTick(() => {
          const message = store.getters.socketMessage;
          console.log("message", message);
          let { flag, data } = message;
          // 监听新消息
          if (flag == "newNotice") {
            if (!props.visible) {
              const key = `open${Date.now()}`;
              notification.open({
                message: data.catInfo.name || "通知",
                description: data.last_title || "您有一条新通知,请及时查看",
                key,
                btn: h(
                  Button,
                  {
                    type: "primary",
                    size: "small",
                    onClick: () => {
                      emit("newMessage");
                      notification.close(key);
                    },
                  },
                  "查看"
                ),
              });
            } else {
              const index = state.messageList.findIndex(
                (item) => item.cat_label == data.cat_label
              );
              if (index == -1) {
                data.un_complete = 1;
              } else {
                data.un_complete = state.messageList[index].un_complete + 1;
                if (
                  state.messageList[index].cat_label ==
                  state.currentMessage.cat_label
                ) {
                  state.newMessageCount = data.un_complete;
                }
              }
              state.messageList.splice(index, 1);
              data.timeStr = common.getDateDiff(data.updated_at);
              state.messageList.unshift(data);
              if (state.listNoData) {
                state.listNoData = false;
              }
            }
          }
          // 监听消息已读
          if (flag == "categoryCompleteCount") {
            if (props.visible) {
              // 更新列表
              const index = state.messageList.findIndex(
                (item) => item.cat_label == data.cat_label
              );
              if (index > -1) {
                state.messageList[index].un_complete = data.un_complete;
              }
              // 更新详情里的状态
              if (
                state.messageList[index].cat_label ==
                  state.currentMessage.cat_label &&
                data.complete_id_arr &&
                data.complete_id_arr.length
              ) {
                state.detailList.forEach((item) => {
                  if (data.complete_id_arr.includes(item.id)) {
                    // 此条已读
                    item.complete = 1;
                  }
                });
              }
            }
          }
        });
      }
    );

    // 连接websocket
    const connentSocket = (config, userInfo) => {
      if (
        config.org &&
        config.org.websocket &&
        config.org.websocket.message &&
        Object.keys(userInfo).length
      ) {
        state.socketServe.connect();
      }
    };

    const init = () => {
      connentSocket(store.getters.returnConfig, store.getters.userInfo);
    };

    watch(
      [() => store.getters.returnConfig, () => store.getters.userInfo],
      ([config, userInfo]) => {
        connentSocket(config, userInfo);
      }
    );

    init();

    watch(
      () => props.visible,
      (val) => {
        if (val) {
          getMssageList();
        } else {
          state.listPage = 1;
          state.messageList = [];
        }
      }
    );

    return {
      ...toRefs(state),
      modalWidth,
      TAB_LIST,
      hiddenUnreadCount,
      handleListItemClick,
      showMessageDetail,
      closeModal,
      handleDetailScroll,
      checkAllUnreadMessage,
      toDetailLink,
      checkNewMessage,
      handleListScroll,
      iframeModalClose,
      setNoticeRead,
    };
  },
});
const INIT_WIDTH = "300px";
const LIST_WIDTH = "70%";
const TAB_LIST = [
  {
    title: "全部",
    key: "0",
  },
  {
    title: "未处理",
    key: "1",
  },
  {
    title: "已完成",
    key: "2",
  },
];
</script>

<style lang="less" scoped>
.flex {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.notice-list {
  height: 100%;
  // border: 1px solid red;
  overflow: hidden;
  .left,
  .right {
    height: 100%;
    overflow: hidden;
    .list {
      overflow: hidden auto;
    }
    .avatar {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      overflow: hidden;
      margin-right: 10px;
      img {
        width: 100%;
        height: 100%;
      }
    }
  }
  .left {
    // border: 1px solid green;
    &:deep(.ant-tabs-bar) {
      margin: 0;
      padding: 0 10px;
    }
    .list {
      // padding: 10px 0;
      height: calc(100% - 40px);
      .message-item {
        display: flex;
        align-items: center;
        padding: 10px 15px;
        overflow: hidden;
        border-bottom: 1px solid #f7f7f7;
        cursor: pointer;

        .info {
          line-height: 24px;
          flex: 1;
          .name {
            &:extend(.flex);
            font-size: 16px;
            color: #000;
            .time {
              color: #999;
              font-size: 12px;
            }
          }
          .last-message {
            &:extend(.flex);
            color: #666;
          }
        }
      }
      .message-active {
        background: @primary-color-bg;
      }
    }
  }
  .right {
    // border: 1px solid blue;
    background: #f7f7f7;
    .content {
      height: 100%;
      position: relative;
      .title {
        height: 60px;
        border-bottom: 1px solid #f1f1f1;
        background: #fafafa;
        display: flex;
        align-items: center;
        padding: 0 10px;
        .info {
          line-height: 24px;
          flex: 1;
          .name {
            color: #000;
            font-size: 16px;
          }
          .intro {
            color: #999;
            font-size: 12px;
          }
        }
      }
      .unread-count {
        position: absolute;
        right: 20px;
        top: 80px;
        padding: 6px 12px;
        background: @primary-color;
        z-index: 100;
        border-radius: 20px;
        color: #fff;
        font-size: 12px;
        cursor: pointer;
      }
      .unread-count2 {
        position: absolute;
        bottom: 40px;
        right: 20px;
        padding: 6px 12px;
        background: @primary-color;
        z-index: 100;
        border-radius: 20px;
        color: #fff;
        font-size: 12px;
        cursor: pointer;
      }
      .list {
        height: calc(100% - 60px);
        &:deep(.ant-card-body) {
          padding: 0px;
        }
        .detail-item {
          margin: 10px 20px;
          .show-time {
            line-height: 30px;
            text-align: center;
            color: #999;
            padding-bottom: 10px;
          }
          .list-content {
            padding: 10px 0;
            .line-item {
              padding: 6px 12px;
            }
          }
        }
        .no-content {
          text-align: center;
          line-height: 40px;
          color: #999;
          font-size: 12px;
        }

        .check-detail {
          &:extend(.flex);
          border-top: 1px solid #f0f0f0;
          padding: 10px;
          cursor: pointer;
        }
      }
    }
    .empty {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: space-around;
    }
  }
}
.beauty-scroller-bar::-webkit-scrollbar-thumb {
  background-color: #999;
}
</style>
